require "lua/puz_gem"
require "lua/puz_func"
require "lua/t_statics"

-- 游戏事件
PFunc_Complete  = 0x01 --结束
PFunc_AddScore  = 0x02 --增加分数
PFunc_Combo     = 0x03 --连击
PFunc_Kills     = 0x04 --杀手怪物
PFunc_Hurts     = 0x05 --受到伤害
PFunc_Timer     = 0x06 --时间回调(s)
PFunc_Swap      = 0x07 --交换开始
PFunc_newRound  = 0x08 --新回合开始


-- 宝石对象父节点
CSP_GemsNode    = 0x01

-- tests scene
local layer = nil
local _gameMode = nil
local _playMode = nil

FillType_Down= 0x01
FillType_Up  = 0x02
G_FillTypeBizz  = FillType_Down
    
----------------- 暂停/
_GameFirst = true
_GameEndRun = false
_gamePause = false    -- 游戏暂停标识
function onGamePause()
    if not _gamePause then
        _gamePause = true
        --CCDirector:sharedDirector():pause()
    else
        _gamePause = false
        --CCDirector:sharedDirector():resume()
    end
end

local AddMoveToGems = nil
Func_BeginResFills = nil

----------全局变量
_GGemTable = {}     -- 宝石表(主键:当前位置index=Gems_Rows*c+r
_GGemTableKeys = {} -- 以key为主键的砖块表
-- 创建的砖块类型
G_PuzGemsList = {Gem_Red, Gem_Yellow, Gem_Blue, Gem_Green}
-- 小鸟模式砖块生成速度(秒
_GameMode_Bizz_NewLine = 0
_GameMode_Bizz_NewLineLt = 0


_drawLineShandian = nil
_ToBomNormalFunc = nil
_Swap_Gems_EndStop = nil
_func_Set_GemPos = nil
_func_DelMoveToGems = nil
_GemTypesbatchNode = nil
local _gemID = 0
-- 获取一个宝石ID
function getGemID()
    _gemID = _gemID + 1
    return _gemID
end

-- 创建宝石    
function createGems(r,c, tpe)
    local gtype = tpe
    if tpe == nil then
        local idx = math.random(1,#G_PuzGemsList)
        gtype = G_PuzGemsList[idx]
    end
    local key = getGemID()
    local obj = Gem:new(key, gtype, r, c, _playMode)
    _GGemTable[getIndex(r,c)] = obj
    _GGemTableKeys[key] = obj
    return obj
end
    
_func_changeToBom = nil
_func_UseToBom = nil
-- 从字典/列表中移除宝石
---动画相关
_deleteSums = 0
_moveSums = 0
_randomBomsSums = 0
local _deleteBomGems_End = nil
local _func_show_deleteeffs = nil
local _func_show_deleterandom = nil
function _func_deleteGem(cgem, bdel, fadeoutt, bomtpe, isStop)
    if cgem ~= nil and not cgem.GoToDelete then
        cgem:on_Puz(bdel)
        local tgem = _GGemTable[getIndex(cgem.row, cgem.col)]
        if tgem ~= nil and tgem.key == cgem.key then
            _GGemTable[getIndex(cgem.row, cgem.col)] = nil
        end
        
        if bdel == nil then
            local bomstt = 0.0
    
            if fadeoutt == nil then
                fadeoutt = Anim_FadeOut
            else
                bomstt = fadeoutt
                fadeoutt = fadeoutt + Anim_FadeOut
            end
            
            _deleteSums = _deleteSums + 1
            
            
            local bomfunc = _func_show_deleteeffs
            if bomtpe == Item_Bom then
                bomfunc = _func_show_deleteeffs
            elseif bomtpe == Item_BomCorss then
                bomfunc = _func_show_deleteeffs_nil
            elseif bomtpe == Item_BomRandom then
                bomfunc = _func_show_deleterandom
            end
            if isStop == nil or isStop then
                cgem:stopActions_Moveto()
            end
            cgem.img:runAction(CCSequence:createWithTwoActions(CCMoveTo:create(bomstt, ccp(cgem:GetPosition())), CCCallFuncN:create(bomfunc)))
        else
            cgem:Remove(layer, _GemTypesbatchNode)
        end
        cgem.GoToDelete = true
        
        -- 如果被消除的等于当前拾取的,则清空拾取
        if _gemPick ~= nil and _gemPick.key == cgem.key then
            _gemPick = nil
        end
        
        --- 炸弹爆炸
        _func_UseToBom(cgem, cgem.bomtype)
    end
end


function _func_deleteGemJump(cgem, bdel, brun, tdelay)
    if cgem ~= nil and not cgem.GoToDelete then
        cgem:on_Puz()
        
        local tgem = _GGemTable[getIndex(cgem.row, cgem.col)]
        if tgem ~= nil and tgem.key == cgem.key then
            _GGemTable[getIndex(cgem.row, cgem.col)] = nil
        end
        
        --跳跃参数(时间,位置,高度,次数
        local mx, my = cgem:GetPosition()
        local st = stime==nil and 1
        local tpx = math.random(0,DWinSizeWidth)
        local tpy = -100
        local jheight = math.random(50,100)
        local action = CCJumpTo:create(st, CCPointMake(tpx, tpy), my + jheight, 1)
        -- 跳动延迟
        if tdelay == nil then
            tdelay = 0.0
        end
        local array = CCArray:create()
        array:addObject(CCMoveTo:create(tdelay, ccp(mx, my)))
        array:addObject(action)
        local seq    = CCSequence:create(array)
        
        if brun == nil then
            --cgem:runAction(seq)
            cgem:Remove(layer, _GemTypesbatchNode)
        else
            cgem:runAction(CCSequence:createWithTwoActions(seq, CCCallFuncN:create(_deleteBomGems_End)))
            _deleteSums = _deleteSums + 1
        end
        cgem.GoToDelete = true
        
        --- 炸弹爆炸
        _func_UseToBom(cgem, cgem.bomtype)
    end
end

_func_show_deleteeffs = function(atcobj)
    local cgem = _GGemTableKeys[atcobj:getTag()]
    if cgem ~= nil then
        cgem:runAction_FadeOut(0.3, _deleteBomGems_End)
        
        local mx,my = getGemPos(cgem.row, cgem.col)
        --local anim = GFunc_CreateAnimation("brick_burst_0000", 0, 8, 1, nil, _ToBomNormalFunc)
        local anim = GFunc_CreateAnimation("disappear_0000", 1, 7, 1, 0.12, _ToBomNormalFunc)
        anim:setPosition(mx, my)
        layer:addChild(anim, 3)
    end
end

_func_show_deleterandom = function(atcobj)
    _func_show_deleteeffs(atcobj)
    --Play_Effect(sme_BrickFadeOut)
end

_func_show_deleteeffs_bomNor = function(atcobj)
    local cgem = _GGemTableKeys[atcobj:getTag()]
    if cgem ~= nil then
        cgem:runAction_FadeOut(0.3, _deleteBomGems_End)
        
        local mx,my = getGemPos(cgem.row, cgem.col)
        local anim = GFunc_CreateAnimation("bomb001_0000", 0, 7, 1, 0.05, _ToBomNormalFunc)
        anim:setPosition(mx, my)
        layer:addChild(anim, 3)
        
        --_func_show_deleteeffs(atcobj)
    end
end

_func_show_deleteeffs_nil = function(atcobj)
    local cgem = _GGemTableKeys[atcobj:getTag()]
    if cgem ~= nil then
        _deleteBomGems_End(atcobj)
        --cgem:runAction_FadeOut(0.0, _deleteBomGems_End)
    end
end

-- 移除所有宝石,崩坏效果
function _func_deleteAllGems()
    --删除所有宝石,宝石向两边移动之后消失,
    table.foreach(_GGemTable, function(k,cgem)
        if cgem ~= nil then
            _func_deleteGemJump(cgem, nil, true)
        end
    end)
    print("allalalla")
    --_GGemTable = {}
    --_gemPick = nil
    --_deleteSums = 0
end
    

------------------------ 初始化((传入需要的参数,宝石类型,游戏模式计分等
function Create_Game_Scene(gameMode, gemList, playMode, gamefunc)
    layer = CCLayer:create()
    
    _GameEndRun = false
    
    _GGemTable = {}
    _GGemTableKeys = {}
    
    _moveSums = 0
    _deleteSums = 0
    _GemTypesbatchNode = nil
    
    _gemID = 0         -- 宝石生成ID
    local _gemPick = nil     -- 当前拾取宝石
    local _gameStats = CGgame_Stats.new() -- 用于统计当前消除状态_计分等
    
    local _gamefunc = gamefunc -- 游戏事件回调
    _playMode = playMode -- 玩法模式
    _gameMode = gameMode -- 游戏模式
    local _GemTypes = nil -- 宝石类型
    
    local _func_Puz_Bom_Gems = nil
    local _func_Puz_Gems = nil  -- 函数变量
    local _func_Judge_Puz = Judge_Puz
    local _func_has_Puz_Gem = has_Puz_Gem
    local _func_has_Puz_Gems = has_Puz_Gems
    local _func_on_PickBizz = on_PickBizz
	local _Fill_UToD_Lite = nil
    local _func_Puz_CreateBoms = nil
    
    
    -- 宝石交换
    local _swap_count = 0
    local _swap_Gem1 = nil
    local _swap_Gem2 = nil
    local _swap_Gem1r = 0
    local _swap_Gem1c = 0
    local _swap_Gem2r = 0
    local _swap_Gem2c = 0
    local _swap_ends = true
    local _swap_toends = false
    
    --炸弹相关
    local _baseLayer_entry = nil --计时器
    local _gameRun = false      -- 游戏运行标识
    local _joinGame = false     -- 进入游戏
    _gamePause = false
    
    --// userinterface
    -- 砖块背景
    local _GemTypesImg = s_Game_BrickAnim
    local _GemTypeSum = 7
    gemSize = 74
    gemSizeH = 74
    if _playMode == PlayMode_TiaoZhan then
        _GemTypeSum = 6
        _GemTypesImg = s_Game_BrickCH
        
        gemPosy = 225
        Gems_Rows   = 8
        Gems_Cols   = 8
        GridWidth = 74
        GridHeight = 74
    else
        if _gameMode == GameMode_Puz then
            gemSize = 70
            gemSizeH = 70
        end
        Gems_Rows   = 8
        Gems_Cols   = 7
        GridWidth = 80
        GridHeight = 80
        
        gemPosy = 200
    end
    gemPosx = (DWinSizeWidth-(Gems_Cols*GridWidth))/2 + GridWidth/2
    gemEndPx = gemPosx + GridWidth * (Gems_Cols-1)
    gemEndPy = gemPosy + GridHeight * (Gems_Rows-1)
    
    _GemTypesbatchNode = CCSpriteBatchNode:create(GetPathRes("gameUI3.png"), Gems_Rows * Gems_Cols * 2)
    layer:addChild(_GemTypesbatchNode,2, CSP_GemsNode)
    CCSpriteFrameCache:sharedSpriteFrameCache():addSpriteFramesWithFile(GetPathRes("gameUI3.plist"))
    
    --- 拾取砖块按钮
    local _pickMenu = CCMenu:create()
    -- 主菜单大小
    _pickMenu:setContentSize(CCSizeMake(DWinSizeWidth,  DWinSizeHeight))
    -- 设置坐标
    _pickMenu:setPosition(0, 0)
    
    
    local _btnPickItem = CCSprite:createWithSpriteFrameName("TEBrick_Pick_01.png")
    _btnPickItem:setPosition(gdccp(0, 0))
    _btnPickItem:setVisible(false)
    layer:addChild(_btnPickItem,3)
    
    local _btnPickItemSwap = CCSprite:createWithSpriteFrameName("TEBrick_Pick_02.png")
    _btnPickItemSwap:setPosition(gdccp(0, 0))
    _btnPickItemSwap:setVisible(false)
    layer:addChild(_btnPickItemSwap,3)
    local _btnPickItemSwap2 = CCSprite:createWithSpriteFrameName("TEBrick_Pick_02.png")
    _btnPickItemSwap2:setPosition(gdccp(0, 0))
    _btnPickItemSwap2:setVisible(false)
    layer:addChild(_btnPickItemSwap2,3)
    --//
    
    -- 游戏变量(可消除的宝石类型(根据关卡需求改变
    G_PuzGemsList = {Gem_Red, Gem_Yellow, Gem_Blue, Gem_Green}
    if gemList ~= nil then
        G_PuzGemsList = gemList
    end
        
    -- 是否进行常规消除(点击消除与交换消除
    local _onPuzClicked = false
    
    --  相当于srand()的过程
    math.randomseed(os.time())
    -- 生成随机宝石阵
        
    ---- 魂力无双用它自带的生成代码
    if _gameMode ~= GameMode_Puz then
        -- 模式:bizz-- 初始生成三列
        local creRows = Gems_Rows-1
        local creCols = Gems_Cols-1
        local bc = 0 
        local br = 0
        if _gameMode == GameMode_Bizz then
            br = Gems_Rows - 3
        end
        
        for r = br, creRows do
            for c = bc, creCols do
                createGems(r,c)
            end
        end
    end
    
    -- 新的消除回合
    local function newRound()
        -- 如果当前没有移动中或者删除中的,则更新回合
        if _moveSums == 0 and _deleteSums == 0 and _randomBomsSums == 0 then
            _gameStats:newRound(Games_Puz)
            
            -- 判断是否结束
            if _gameMode == GameMode_Bizz then
                _gamefunc[PFunc_Complete]()
                --回合各自的位置
                table.foreach(_GGemTable, function(k,cgem)
                    if cgem ~= nil and not cgem.isBomed and (_gemPick == nil or _gemPick.key ~= cgem.key) then
                        local lpx, lpy = cgem:GetPosition()
                        local tpx, tpy = getGemPos(cgem.row, cgem.col)
                        if lpx ~= tpx or lpy ~= tpy then
                            _func_Set_GemPos(cgem, cgem.row, cgem.col)
                        end
                    end
                end)
            else
                _gamefunc[PFunc_newRound]()
            end
        end
    end
    
    
    --清空拾取
    local function clearPicks()
        _gemPick = nil -- 清空拾取
        _btnPickItem:setVisible(false)
    end
    local function onPickGems(gem)
        _gemPick = gem
        if _gameMode == GameMode_Bizz then
            _gemPick.isMoved = true
        end
        if _gameMode == GameMode_Puz then
            _btnPickItem:setVisible(true)
        end
        local px,py = gem:GetPosition()
        _btnPickItem:setPosition(ccp(px,py))
        --print("pick__",px,py)
    end
    
    
    --从最后一排上升一层宝石
    local function Fill_Gems_LastRow()
        -- 所有原来的宝石上移一个空位,第一开始
        --print(_gemPick)
        for c=0,Gems_Cols-1 do
            if _GGemTable[getIndex(0,c)] == nil or (_gemPick ~= nil and _gemPick.key == _GGemTable[getIndex(0,c)].key) then
                for r=1,Gems_Rows-1 do
                    local cgem = _GGemTable[getIndex(r,c)]
                    if cgem ~= nil then
                        if (r==1 and _GGemTable[getIndex(0,c)] ~= nil and _gemPick ~= nil and _gemPick.key == _GGemTable[getIndex(0,c)].key) then
                            break
                        end
                        _func_Set_GemPos(cgem, cgem.row-1, cgem.col)
                    end
                end
            end
        end
        -- 新的宝石在最后一行生成
        local r = Gems_Rows-1
        for c=0,Gems_Cols-1 do
            -- 如果当前行宝石没有满的话
            if _GGemTable[getIndex(r,c)] == nil then
                cgem = createGems(r, c)
                local x, y = getGemPos(r+1, c)
                cgem.img:setPosition(x,y)
                _func_Set_GemPos(cgem, r, c)
            end
        end
    end
    --从第一排上落下一层宝石
    local function Fill_Gems_FirstRow()
        -- 新的宝石在第一行生成
        for c=0,Gems_Cols-1 do
            --向下找到没有宝石的行
            local r = 0
            while r < Gems_Rows and _GGemTable[getIndex(r,c)] == nil do
                r = r + 1
            end
            
            r = r - 1
            if r >= 0 then
                -- 如果当前行宝石没有满的话
                if _GGemTable[getIndex(r,c)] == nil then
                    cgem = createGems(r, c)
                    local x, y = getGemPos(-1, c)
                    cgem.img:setPosition(x,y)
                    _func_Set_GemPos(cgem, r, c)
                end
            end
        end
    end
    
    local function Fill_Bizz_Thr()
        if _gemPick == nil then
            -- 如果当前所有宝石数量少于3行数量,则从下方添加一行宝石
            local sums = 0
            for k, cgem in pairs(_GGemTable) do
                if cgem ~= nil then
                    sums = sums + 1
                end
            end
            if sums < Gems_Cols * 3 then
                -- 所有原来的宝石上移一个空位,第一开始
                for c=0,Gems_Cols-1 do
                    if _GGemTable[getIndex(0,c)] == nil then
                        for r=1,Gems_Rows-1 do
                            local cgem = _GGemTable[getIndex(r,c)]
                            if cgem ~= nil then
                                _func_Set_GemPos(cgem, cgem.row-1, cgem.col)
                            end
                        end
                    end
                end
                -- 新的宝石在最后一行生成
                local r = Gems_Rows-1
                for c=0,Gems_Cols-1 do
                    -- 如果当前行宝石没有满的话
                    if _GGemTable[getIndex(r,c)] == nil then
                        cgem = createGems(r, c)
                        local x, y = getGemPos(r+1, c)
                        cgem.img:setPosition(x,y)
                        _func_Set_GemPos(cgem, r, c)
                    end
                end
            end
        end
    end
    -- 移动结束动画
    local _BizzPuzs_Ready = {}
    
    --爆炸确认
    local function ToBizzMastBom(actobj)
        local tobomsobj = _BizzPuzs_Ready[actobj:getTag()]
        local toboms = tobomsobj.dobj
        local togems = tobomsobj.gems
        -- 在消除过程中可能会被炸弹炸掉,所以需要确认
        
        for k, index in pairs(toboms.delgems) do
            local ddgem = _GGemTable[index]
            if ddgem then
                if togems[ddgem.key] == nil then
                    toboms.delgems[k] = -1000
                end
            end
        end
        
        if toboms then
            _func_Puz_Bom_Gems({toboms})
        end
        _BizzPuzs_Ready[actobj:getTag()] = nil
    end
    
    local function _Bizz_Move_Ends(cgem)
        -- 全部移动完成,再次判定消除
        if _gemPick == nil or _gemPick.key ~= cgem.key then
            -------  如果正在爆炸状态中,则丢弃
            if cgem.isBomed then
                return
            end
            
            local mx,my = cgem:GetPosition()
            local lrow, lcol = getGemGrid(gdvc(mx), gdvc(my))
                        
            --如果下面有空位,就显示移动
            local ddgem = _GGemTable[getIndex(lrow + 1, lcol)]
            if lrow >= 0 and lrow + 1 < Gems_Rows then
                if ddgem == nil then
                    --print("_Bizz_Move_Ends",lrow+1,lcol)
                    _Fill_UToD_Lite_Bizz(lrow + 1, lcol)
                    return
                else
                    for i=lrow+1,Gems_Rows-1 do
                        local ddgem = _GGemTable[getIndex(i, lcol)]
                        if ddgem == nil or (_gemPick ~= nil and _gemPick.key == ddgem.key) then
                            return
                        end
                    end
                end
            end
            
            -- 相邻/连接即可
            local has, delobj = has_Puz_GemCon(_GGemTable, cgem)
            
            --记录砖块的key
            local toBomgems = {}
            -- 直接消除
            if has and #delobj.delgems > Puz_Number then
                --抖动
                local sogems = nil --判定主
                local sumtime = 7
                for k, index in pairs(delobj.delgems) do
                    local ddgem = _GGemTable[index]
                    if ddgem then
                        toBomgems[ddgem.key] = true
                        ---删除已经存在的
                        if _BizzPuzs_Ready[ddgem.key] then
                            _BizzPuzs_Ready[ddgem.key] = nil
                        end
                        
                        local mx,my = ddgem:GetPosition()
                        
                        local array = CCArray:create()
                        local ddfps = gdv(5)
                        for i=0,sumtime do
                            local tx = mx
                            local ty = my
                            if i % 2 == 0 then
                                tx, ty = mx + math.random(-ddfps,ddfps), my + math.random(-ddfps,ddfps)
                            end
                            array:addObject(CCMoveTo:create(0.1, ccp(tx, ty)))
                        end
                        local seq = CCSequence:create(array)
                        ddgem.img:setScale(1.0)
                        ddgem.img:stopAllActions()
                        ddgem:runAction(seq)
                        
                        sogems = ddgem
                        
                        --- 爆炸状态
                        ddgem.isBomed = true
                    end
                end
                
                if sogems then
                    -- 消除准备中
                    _BizzPuzs_Ready[sogems.key] = {dobj=delobj, gems=toBomgems}
                    -- 时间到后消除
                    local mx, my = sogems:GetPosition()
                    sogems:runAction(CCSequence:createWithTwoActions(CCScaleTo:create((sumtime+1)*0.1, 1.0), CCCallFuncN:create(ToBizzMastBom)))
                end
            end
        end
    end
    
    local function Move_Gems_End(actobj)
        local cgem = _GGemTableKeys[actobj:getTag()]
        if cgem == nil then
            return
        end
        cgem:onMoveEnd()
        cgem.isHeCheng = false
        
        if _GameFirst then
            _GameFirst = false
        end
        
        if _GameEndRun then
            return
        end
        
        if _gameMode == GameMode_Clicked then
        elseif _gameMode == GameMode_Bizz then
            _Bizz_Move_Ends(cgem)
        else
            if cgem ~= nil then
                local has, rvalue = _func_has_Puz_Gem(_GGemTable, cgem.tpe, cgem.row, cgem.col, cgem.key)
                -- 如果有可消除,就重复消除操作
                if #rvalue > 0 then
                    -- 需要生成炸弹
                    _func_Puz_Bom_Gems(rvalue)
                end
                --print("___",#rvalue)
            end
        end
        
        --新回合判定
        newRound()
    end
    
    -- 添加移动
    AddMoveToGems = function(cgem, trow, tcol, bfunc)
        if not cgem.isremove then
            local mypx, mypy = cgem:GetPosition()
            
            if trow == nil then
                trow = cgem.row
            end
            
            if tcol == nil then
                tcol = cgem.col
            end
            
            local func = nil
            if bfunc == nil then
                func = Move_Gems_End
            end
            
            local x, y = getGemPos(trow, tcol)
            local vlenght = ccpLength(ccp(mypx - x, mypy - y))
            cgem:runAction_MoveTo(Anim_MoveTimes * (vlenght/gemSize), ccp(x,y), func)
            _moveSums = _moveSums + 1
        end
    end
    
    _func_DelMoveToGems = function(cgem)
        if cgem.isMoved then
            _moveSums = _moveSums - 1
        end
    end
    
    -- 设置宝石的位置
    _func_Set_GemPos = function(cgem, toRow, toCol, bmove)
        if toRow == nil then
            toRow = -1
        end
        if toCol == nil then
            toCol = -1
        end
        if cgem == nil then
            return
        end
        
        if bmove == nil then
            bmove = true
        end
        
        if _GGemTable[getIndex(cgem.row, cgem.col)] == nil or _GGemTable[getIndex(cgem.row, cgem.col)].key ~= cgem.key then
            return
        end
        
        local swapaaa = false
        if toRow ~= -1 and toCol ~= -1 then
            _GGemTable[getIndex(cgem.row, cgem.col)] = _GGemTable[getIndex(toRow, toCol)]
            cgem.row = toRow
            cgem.col = toCol
            swapaaa = true
        end
        if not swapaaa and _GGemTable[getIndex(cgem.row, cgem.col)].key ~= cgem.key then
            return
        end
        _GGemTable[getIndex(cgem.row, cgem.col)] = cgem
        
        -- 添加移动
        if bmove then
            AddMoveToGems(cgem)
        end
    end
    
    _Fill_UToD_Lite = function(row, col, newlist)
        if row == nil then
            row = Gems_Rows - 1
        end
        
        if newlist == nil then
            newlist = {}
        end
        
        while row >= 0 do
            -- 只需要把宝石移动下面有空的位置中就可以了
            local cgem = _GGemTable[getIndex(row, col)]
            local onmove = true
            if cgem ~= nil then
                --排除当前拾取
                if _gameMode == GameMode_Bizz and _gemPick ~= nil then
                    if cgem.key == _gemPick.key or (not cgem:onIsPuz()) then
                        onmove = false
                    end
                end
                
                --取消拾取
                if _gameMode == GameMode_Puz and _gemPick ~= nil then
                    if cgem.key == _gemPick.key then
                        clearPicks()
                    end
                end
                
                --不是交换中的
                if _swap_Gem1 ~= nil then
                    if cgem.key == _swap_Gem1.key then
                        onmove = false
                        break
                    end
                end
                if _swap_Gem2 ~= nil then
                    if cgem.key == _swap_Gem2.key then
                        onmove = false
                        break
                    end
                end
                
                --不是爆炸中的
                if cgem.isBomed then
                    onmove = false
                end
                
                -- 找到下面的空位置,移动
                if onmove then
                    local brow = row + 1
                    local trow = nil
                    while brow < Gems_Rows do
                        if _GGemTable[getIndex(brow, col)] == nil then
                            trow = brow
                        else
                            break
                        end
                        brow = brow + 1
                    end
                    
                    if trow ~= nil then
                        _func_Set_GemPos(cgem, trow, col)
                        table.insert(newlist, cgem)
                    end
                end
            end
            row = row - 1
        end
    end
    
    -- 当前行列往下沉-爆炸
    _Fill_UToD_Lite_Bizz = function(row, col)
        isDowns = false
        
        if true then
            _Fill_UToD_Lite(row, col)
            return isDowns
        end
        
        --- 找到空列
        local trow = Gems_Rows-1
        while trow >= 0 do
            local cgem = _GGemTable[getIndex(trow, col)]
            
            --排除当前拾取
            if cgem == nil then 
                break
            end
            
            trow = trow - 1
        end
        --找到非空列
        local mrow = trow
        while mrow >= 0 do
            local cgem = _GGemTable[getIndex(mrow, col)]
            
            --排除当前拾取
            if cgem ~= nil then 
                local onmove = true
                -- 非移动,爆炸,移动中
                if (_gemPick and cgem.key == _gemPick.key) or (not cgem:onIsPuz()) then
                    onmove = false
                end
        
                if onmove then
                    break
                end
            end
            
            mrow = mrow - 1
        end
        --- 所有都往下移动
        local maingem = _GGemTable[getIndex(mrow, col)]
        while mrow >= 0 do
            local cgem = _GGemTable[getIndex(mrow, col)]
        
            --排除当前拾取
            local onmove = true
            if cgem ~= nil then
                if (_gemPick and cgem.key == _gemPick.key) or cgem.isBomed then
                    onmove = false
                end
            
                if onmove then
                    --更新当前位置
                    _func_Set_GemPos(cgem, trow, col)
                    
                    isDowns = true
                end
            end
            
            mrow = mrow - 1
            trow = trow - 1
        end
        
        return isDowns
    end
    
    -- 宝石从上往下填充
    local function Fill_UToD()
        local newlist = {}
        --** 以左到右,下到上的方式搜索是否有空位
        --** 发现空位后寻找往上寻找有宝石的位置,之后依次移动到最下面的空位
        local col = 0
        while col < Gems_Cols do
            _Fill_UToD_Lite(Gems_Rows - 1, col, newlist)
            col = col + 1
        end
        
        return newlist
    end
    
    
    -- 为空位重新添加宝石
    local function Fill_Gems(self)
        -- 记录每列宝石已经生成的个数,用于设置生成宝石的初始位置
        local colsCut = {}
        
        -- 宝石新生成的宝石
        local newlist = {}
        
        for col=0,Gems_Cols-1 do
            local brow = Gems_Rows
            for row=0,Gems_Rows-1 do
                local cgem = _GGemTable[getIndex(row, col)]
                if cgem ~= nil then
                    brow = row
                    break
                end
            end
            while brow > 0 do
                brow = brow - 1
                cgem = createGems(brow, col)
                table.insert(newlist, cgem)
                -- 初始位置需要在屏幕上方,从上往下落
                if colsCut[col] == nil then
                    colsCut[col] = 0
                end
                colsCut[col] = colsCut[col] + 1
                
                local x, y = getGemPos(-colsCut[col], col)
                cgem.img:setPosition(x,y)
                _func_Set_GemPos(cgem, cgem.row, cgem.col)
            end
        end
        
        return newlist
    end
    
    -- 重新排放宝石,填充空位并新增宝石
    function Sort_Gems_Fill()
        if _randomBomsSums > 0 then
            return
        end
        --排序旧宝石
        local newlist = Fill_UToD()
        --为空的位置填充宝石
        local newlist2 = Fill_Gems()
        --连接两个
        for i,v in pairs(newlist2) do
            table.insert(newlist,v)
        end
    end
    
    
    -- 消除/爆炸动画结束
    _deleteBomGems_End = function(actobj)
        local cgem = _GGemTableKeys[actobj:getTag()]
        _deleteSums = _deleteSums - 1
        --print("desum:",_deleteSums)
        if cgem ~= nil and cgem.isremove == false then
            cgem:Remove(layer, _GemTypesbatchNode)
        end
        
        if _deleteSums == 0 then
            if _gameMode == GameMode_Bizz then
                -- 自动排列
                local rlist = Fill_UToD()
                -- 移动完成后,如果没有需要消除的,则判定是否填充>>如果当前拾取着宝石,则不填充
                if #rlist == 0 then
                    --Fill_Bizz_Thr()
                end
            elseif _gameMode == GameMode_Puz or _gameMode == GameMode_Clicked then
                -- 重新填充宝石((消除动画结束后重新排列
                --print("newSort")
                Sort_Gems_Fill()
            end
        end
        --新回合判定
        newRound()
    end
    
    -----------宝石交换回调参数
    
    -- 真正交换
    local function Swap_Gems_God()
        --位置交换
        trow = _swap_Gem1.row
        tcol = _swap_Gem1.col
        _swap_Gem1.row = _swap_Gem2.row
        _swap_Gem1.col = _swap_Gem2.col
        _swap_Gem2.row = trow
        _swap_Gem2.col = tcol
        --更新表格
        _GGemTable[getIndex(_swap_Gem1.row, _swap_Gem1.col)] = _swap_Gem1
        _GGemTable[getIndex(_swap_Gem2.row, _swap_Gem2.col)] = _swap_Gem2
        
        
        _swap_Gem1.isSwap = false
        _swap_Gem2.isSwap = false
    end
    
    ----交换结束,QZ=强制清除
    _Swap_Gems_EndStop = function (atcobj, key, QZ)
        local tag = nil
        if _gameMode == GameMode_Puz then
            if atcobj ~= nil then
                tag = atcobj:getTag()
            elseif key ~= nil then
                tag = key
            end
            if tag ~= nil and (_swap_count == 0 or QZ) then
                if _swap_Gem1 ~= nil and _swap_Gem1.key == tag then
                    _swap_Gem1.isMoved = false
                    _swap_Gem1.isSwap = false
                    _swap_Gem1 = nil
                end
                if _swap_Gem2 ~= nil and _swap_Gem2.key == tag then
                    _swap_Gem2.isMoved = false
                    _swap_Gem2.isSwap = false
                    _swap_Gem2 = nil
                end
                
                if _swap_Gem1 == nil and _swap_Gem2 == nil then
                    _swap_count = 0
                end
            end
            
            if _swap_toends and _swap_Gem2 == nil and _swap_Gem1 == nil then
                _swap_ends = true
                _swap_toends = false
                Sort_Gems_Fill()
            end
        end
    end
    
    -- 交换动画结束
    local function Swap_Gems_End()
        _swap_count = _swap_count - 1
        if _swap_count == 0 then
            --交换移动完成
            --状态清空
            if _gemPick then
                _gemPick:rState()
            end
            
            _swap_Gem1.isSwap = false
            _swap_Gem2.isSwap = false
            
            --判断是否可消除
            has,rvalue = _func_has_Puz_Gems(_GGemTable, _swap_Gem1, _swap_Gem2)
            if has then
                Swap_Gems_God()
                --消除
                --_func_Puz_Gems(rvalue)
                _func_Puz_Bom_Gems(rvalue)
                
                
                if _swap_Gem1 ~= nil then
                    _swap_Gem1:onMoveEnd()
                end
                if _swap_Gem2 ~= nil then
                    _swap_Gem2:onMoveEnd()
                end
                
                _swap_ends = true
            else
                local tempsp1 = _swap_Gem1
                local tempsp2 = _swap_Gem2
                -- 返回原位
                if _swap_Gem1r == _swap_Gem1.row and _swap_Gem1c == _swap_Gem1.col then
                    _swap_Gem1:swapTo(_swap_Gem1.row, _swap_Gem1.col, _Swap_Gems_EndStop)
                    _moveSums = _moveSums + 1
                end
                
                if _swap_Gem2r == _swap_Gem2.row and _swap_Gem2c == _swap_Gem2.col then
                    _swap_Gem2:swapTo(_swap_Gem2.row, _swap_Gem2.col, _Swap_Gems_EndStop)
                    _moveSums = _moveSums + 1
                end
                _swap_Gem1 = tempsp1
                _swap_Gem2 = tempsp2
                _swap_toends = true
            end
            clearPicks()
        end
        
        _btnPickItemSwap2:setVisible(false)
        _btnPickItemSwap:setVisible(false)
    end
    
    local lastSwapTime = os.clock()
    -- 交换宝石位置
    local function Swap_Gems(gem1, gem2)
        --两个宝石移动到新的位置,到达之后判定消除
        --记录其当前位置,如果无法消除则返回之前位置
        _swap_count = _swap_count + 2
        _swap_Gem1 = gem1
        _swap_Gem2 = gem2
        
        -- 记录用于判定是否在交换期间移动了位置
        _swap_Gem1r = _swap_Gem1.row
        _swap_Gem1c = _swap_Gem1.col
        _swap_Gem2r = _swap_Gem2.row
        _swap_Gem2c = _swap_Gem2.col
        
        _moveSums = _moveSums + 2
        _swap_ends = false
        _swap_Gem1:swapTo(_swap_Gem2.row, _swap_Gem2.col, Swap_Gems_End)
        _swap_Gem2:swapTo(_swap_Gem1.row, _swap_Gem1.col, Swap_Gems_End)
        
        if _gamefunc[PFunc_Swap] ~= nil then
            _gamefunc[PFunc_Swap](gem1,gem2)
        end
        
        lastSwapTime = os.clock()
        
        
        -- 显示交换框
        local px,py = _swap_Gem1:GetPosition()
        _btnPickItemSwap2:setPosition(ccp(px,py))
        _btnPickItemSwap2:setVisible(true)
        local px,py = _swap_Gem2:GetPosition()
        _btnPickItemSwap:setPosition(ccp(px,py))
        _btnPickItemSwap:setVisible(true)
        
        _btnPickItem:setVisible(false)
    end
    
    -- 是否可以交换
    local function has_Swap(gemn, gemv)
        -- 判断是否在旁边
        vcol = gemn.col - gemv.col
        vrow = gemn.row - gemv.row
        if math.abs(vrow) <= 1 and math.abs(vcol) <= 1 then
            if math.abs(vrow) + math.abs(vcol) <= 1 then
                return true
            end
        end
        
        return false
    end
    
    ----------------- 炸弹效果及爆炸
    -- 消除粒子
    local function ToBomFunc(a1)
        layer:removeChild(a1, true)
    end
    -- 消除粒子与砖块,普通
    _ToBomNormalFunc = function(a1)
        a1:runAction(CCSequence:createWithTwoActions(CCFadeTo:create(Anim_FadeOut, 0), CCCallFuncN:create(ToBomFunc)))
    end
    ---- 消除粒子与砖块(随机
    local function ToBomSceFunc(a1)
        layer:removeChildByTag(a1:getTag(), true)
        layer:removeChildByTag(a1:getTag()-1, true)
    end
    ---- 随机爆炸
    local function ToBomRandomFunc(a1)
        layer:removeChild(a1, true)
        -- 获得其位置,得到宝石,爆炸
        local mx, my = a1:getPosition()
        local r, c = getGemGrid(mx, my)
        local cgem = _GGemTable[getIndex(r,c)]
        _func_deleteGem(cgem)
    end
    
    local _bomtag = 1000000
    local function getBomTag()
        _bomtag = _bomtag + 1
        return _bomtag
    end
    
    _func_UseToBom = function(cgem, bomtype)
        if cgem == nil or bomtype == nil then
            return
        end
        cgem.bomtype = nil
        _gameStats:set_datas(Games_Puz, GSPuz_Cot)
        
        Func_DataStatis(DS_UseBom, bomtype)
        
        if bomtype == Item_Bom then
            Play_Effect(sme_BomH2)
            
            local mx,my = getGemPos(cgem.row, cgem.col)
            mx = gdv(DWinSizeWidth/2)
            local anim = GFunc_CreateAnimation("row_burst_0000", 1, 10, 1, 0.12, _ToBomNormalFunc)
            anim:setPosition(ccp(mx, my))
            layer:addChild(anim, 3)
            anim:setTag(getBomTag())
            
            ---砖块爆炸
            local sums = 0
            -- 模拟消失
            local dtimev = 0.7
            _func_deleteGem(cgem, nil, dtimev, Item_Bom)
            cgem:runAction_FadeOut(Anim_FadeOut)
            for c=0,Gems_Cols do
                local _bomgem = _GGemTable[getIndex(cgem.row, c)]
                if _bomgem ~= nil then -- and not _bomgem.isMoved then
                    -- 模拟消失
                    --_bomgem:runAction_FadeOut(Anim_FadeOut)
                    -- 先从相应位置移除
                    _func_deleteGem(_bomgem, nil, dtimev, Item_Bom)
                    sums = sums + 1
                end
            end
            
            --------先增加分数
            _gamefunc[PFunc_Combo](_gameStats:get_datas(Games_Puz, GSPuz_Cot), sums, cgem)
            
        elseif bomtype == Item_BomArce then
            Play_Effect(sme_BomArce)
            
            --print("Item_BomArce")
            --- 周围的8块
            local glist = {}
            local function _func_d_toBoms(r,c)
                if r < 0 or c < 0 or r >= Gems_Rows or c >= Gems_Cols then
                    return
                end
                local dgcgem = _GGemTable[getIndex(r, c)]
                if dgcgem ~= nil then-- and not dgcgem.isMoved then
                    table.insert(glist, dgcgem)
                end
            end
            
            _func_d_toBoms(cgem.row, cgem.col)
            _func_d_toBoms(cgem.row, cgem.col-1)
            _func_d_toBoms(cgem.row, cgem.col+1)
            _func_d_toBoms(cgem.row-1, cgem.col)
            _func_d_toBoms(cgem.row-1, cgem.col-1)
            _func_d_toBoms(cgem.row-1, cgem.col+1)
            _func_d_toBoms(cgem.row+1, cgem.col)
            _func_d_toBoms(cgem.row+1, cgem.col-1)
            _func_d_toBoms(cgem.row+1, cgem.col+1)
            
            
            local mx,my = getGemPos(cgem.row, cgem.col)
            local anim = GFunc_CreateAnimation("aoe_burst_0000", 0, 7, 1, 0.12, _ToBomNormalFunc)
            anim:setPosition(mx, my)
            layer:addChild(anim, 3)
            anim:setTag(getBomTag())
            
            ---砖块爆炸
            local sums = 0
            for k, _bomgem in pairs(glist) do
                sums = sums + 1
                ----不可拾取
                _bomgem:setPick(false)
                
                _func_deleteGem(_bomgem, nil, 0.7)
            end
            --------先增加分数
            _gamefunc[PFunc_Combo](_gameStats:get_datas(Games_Puz, GSPuz_Cot), sums, cgem)
            
        elseif bomtype == Item_BomCorss then
            Play_Effect(sme_BomCross)
            
            --同行同列的砖块
            local sums = 0
            local fade = 0.5
            for r = 0,Gems_Rows - 1 do
                local _bomgem = _GGemTable[getIndex(r, cgem.col)]
                if _bomgem ~= nil and _bomgem.col == cgem.col then
                    _func_deleteGem(_bomgem, nil, fade)
                    sums = sums + 1
                end
            end
            for c = 0, Gems_Cols - 1 do
                local _bomgem = _GGemTable[getIndex(cgem.row, c)]
                if _bomgem ~= nil and _bomgem.row == cgem.row then
                    _func_deleteGem(_bomgem, nil, fade)
                    sums = sums + 1
                end
            end
            _gamefunc[PFunc_Combo](_gameStats:get_datas(Games_Puz, GSPuz_Cot), sums, cgem)
            
            
            --四周
            local mx,my = getGemPos(cgem.row, cgem.col)
            local w = gdv(98)
            local files = "bombunit_0000"
            local bfr = 0
            local efr = 10
            local loop = 1
            
            local pleft = gdv(GridWidth * cgem.col)
            local pright = gdv(GridWidth * (Gems_Cols - cgem.col - 1))
            local pdown = gdv(GridHeight * (Gems_Rows - cgem.row - 1))
            local pup = gdv(GridHeight * cgem.row)
            local cup = math.floor(pup / w)
            local cdown = math.floor(pdown / w)
            local cleft = math.floor(pleft / w)
            local cright = math.floor(pright / w)
            
            --上
            local gbaozou = nil
            if cgem.row ~= 0 then
                for i=0, cup do
                    gbaozou = GFunc_CreateAnimation(files, bfr, efr, loop, nil, ToBomFunc)
                    local tpy =  my + i * w
                    if tpy + w > pup + my then
                        tpy = pup + my - w
                    end
                    gbaozou:setPosition(ccp(mx, tpy))
                    gbaozou:setAnchorPoint(ccp(1, 0.5))
                    gbaozou:setRotation(90)
                    gbaozou:setFlipX(true)
                    layer:addChild(gbaozou, 3)
                end
            end
            ----下
            if cgem.row ~= Gems_Rows - 1 then
                for i=0, cdown do
                    gbaozou = GFunc_CreateAnimation(files, bfr, efr, loop, nil, ToBomFunc)
                    local tpy =  my - i * w
                    if tpy < my - pdown + w then
                        tpy = my - pdown + w
                    end
                    gbaozou:setPosition(ccp(mx, tpy))
                    gbaozou:setAnchorPoint(ccp(0, 0.5))
                    gbaozou:setRotation(90)
                    layer:addChild(gbaozou, 3)
                end
            end
            ----左
            if cgem.col ~= 0 then
                for i=0, cleft do
                    gbaozou = GFunc_CreateAnimation(files, bfr, efr, loop, nil, ToBomFunc)
                    local tpx = mx - i * w
                    if tpx - w < mx - pleft then
                        tpx = mx - pleft + w
                    end
                    gbaozou:setPosition(ccp(tpx, my))
                    gbaozou:setAnchorPoint(ccp(1, 0.5))
                    gbaozou:setFlipX(true)
                    layer:addChild(gbaozou, 3)
                end
            end
            --右
            if cgem.col ~= Gems_Cols - 1 then
                for i=0,cright do
                    local tpx =  mx + i * w
                    if tpx > pright + mx - w then
                        tpx = pright + mx - w
                    end
                    gbaozou = GFunc_CreateAnimation(files, bfr, efr, loop, nil, ToBomFunc)
                    gbaozou:setPosition(ccp(tpx, my))
                    gbaozou:setAnchorPoint(ccp(0, 0.5))
                    layer:addChild(gbaozou, 3)
                end
            end
            --中心
            local anim = GFunc_CreateAnimation("bombcenter_0000", 0, 11, 1, 0.12, ToBomFunc)
            anim:setPosition(ccp(mx, my))
            layer:addChild(anim, 3)
                
        elseif bomtype == Item_BomRandom then
            -- 起始位置为随机炸弹位置
            local mx,my = getGemPos(cgem.row, cgem.col)
            
            -- 随机选择一个宝石类型,从消除宝石位置,飞出粒子,清除所有此类宝石,每个粒子飞向一颗宝石然后消除
            --随机类型
            local idx = math.random(1,#G_PuzGemsList)
            local gtype = G_PuzGemsList[idx]
            -- 所有此类型宝石
            local glist = {}
            --cgem:setPick(false)
            table.insert(glist, cgem)
            cgem.tpe = gtype
            cgem.bomtype = nil
            --cgem.isBomed = true
            
            table.foreach(_GGemTable, function(k, fgem)
                if fgem ~= nil and fgem.tpe == gtype then
                    table.insert(glist, fgem)
                    --不可拾取
                    --fgem:setPick(false)
                end
            end)
            
            
            --------先增加分数
            _gamefunc[PFunc_Combo](_gameStats:get_datas(Games_Puz, GSPuz_Cot), #glist, cgem)
            
            
            local nlist = {}
            --随机对宝石排序
            --第一点为起点
            --local tpx , tpy = getGemPos(cgem.row, cgem.col)
            --table.insert(nlist, {pos=ccp(tpx,tpy),obj=cgem,})
            local first = true
            while #glist > 0 do
                local idx = math.random(1,#glist)
                
                if first then
                    idx = 1
                    first = false
                end
                
                local dcg = glist[idx]
                table.remove(glist, idx)
                --dcg.isBomed = true
                
                --当前位置与周围4个
                local objls = {}
                table.insert(objls, dcg)
                table.insert(objls, _GGemTable[getIndex(dcg.row,dcg.col+1)])
                table.insert(objls, _GGemTable[getIndex(dcg.row,dcg.col-1)])
                table.insert(objls, _GGemTable[getIndex(dcg.row+1,dcg.col)])
                table.insert(objls, _GGemTable[getIndex(dcg.row-1,dcg.col)])
                
                --if dcg.key ~= cgem.key then
                local tpx , tpy = getGemPos(dcg.row, dcg.col)
                table.insert(nlist, {pos=ccp(tpx,tpy),objlist=objls,})
                --end
            end
            
            table.foreach(nlist, function(k, info)
                if info.objlist ~= nil then
                    table.foreach(info.objlist, function(k1, obj)
                        --obj.isBomed = true
                    end)
                end
            end)
            
            Lightning_New(nlist, Sort_Gems_Fill)
            
            _func_deleteGem(cgem)
        end
        
    end
    
    
    
    
    local function onPick_Bizz(cgem)
        -- 模式:bizz
        
        
        --- 爆炸状态中不可拾取
        if cgem.isBomed then
            return
        end
        
        -- 拾取--是否可拾取
        if _func_on_PickBizz(_GGemTable, cgem) then
            --gem:onPick()
            onPickGems(cgem)
        end
    end
    
    -- 拾取/交换 宝石
    local function Pick_Gems(gem, newPick)
        if nil == newPick then
            newPick = true
        end
        
        ---- 拾取的宝石移动中,则无效
        --print(gem.isMoved ,gem.GoToDelete , gem.isHeCheng, gem.isBomed , gem.isremove, _moveSums, _deleteSums, _randomBomsSums)
        
        if gem.isHeCheng and _deleteSums == 0 and _randomBomsSums == 0 then
            gem.isHeCheng = false
        end
        
        if gem.isMoved or gem.GoToDelete or gem.isHeCheng or gem.isBomed or gem.isremove then
            return
        end
        
        
        -- 模式:Clicked
        if _gameMode == GameMode_Clicked then
            --如果是炸弹则直接爆炸
            if gem.bomtype ~= nil then
                _func_UseToBom(gem, gem.bomtype)
            else
                -- 相邻/连接即可
                local has, delobj = has_Puz_GemCon(_GGemTable, gem)
                -- 直接消除
                
                if has and #delobj.delgems > Puz_Number then
                    ---随机机率生成炸弹
                    local rdm = math.random(1,100)
                    if rdm <= 1 then
                        local gemlist = {}
                        for k1, index in pairs(delobj.delgems) do
                            cgem = _GGemTable[index]
                            if cgem ~= nil then
                                if gemlist[cgem.key] == nil then
                                    gemlist[cgem.key] = cgem
                                end
                            end
                        end
                        
                        local rgsum = math.random(4,7)
                        _func_Puz_CreateBoms(delobj, rgsum, gemlist)
                    else
                        --消除
                        _func_Puz_Gems({delobj})
                    end
                end
            end
        elseif _gameMode == GameMode_Bizz then
            if gem.bomtype == Item_BomRandom then
                ------ 随机炸弹引爆
                _func_UseToBom(gem, Item_BomRandom)
            else
                onPick_Bizz(gem)
            end
        else
            ------- Bom:判断是否是炸弹,随机炸弹触发即引爆
            local btype = gem:isBom()
            if _gemPick == nil and btype == Item_BomRandom then
                ------ 随机炸弹引爆
                _func_UseToBom(gem, Item_BomRandom)
            else
                if (_swap_Gem1 ~= nil or _swap_Gem2 ~= nil) and os.clock() - lastSwapTime > 2 then
                    if _swap_Gem1 ~= nil then
                        _swap_Gem1:onMoveEnd()
                        
                        local mx,my = getGemPos(_swap_Gem1.row, _swap_Gem1.col)
                        _swap_Gem1:onMoveTo(mx ,my)
                        
                        _swap_Gem1.isMoved = false
                        _swap_Gem1.isSwap = false
                        _swap_Gem1 = nil
                    end
                    
                    if _swap_Gem1 ~= nil then
                        _swap_Gem2:onMoveEnd()
                        
                        local mx,my = getGemPos(_swap_Gem2.row, _swap_Gem2.col)
                        _swap_Gem2:onMoveTo(mx ,my)
                        
                        _swap_Gem2.isMoved = false
                        _swap_Gem2.isSwap = false
                        _swap_Gem2 = nil
                    end
                end
                
                --如果交换中,则不可以交换
                if _swap_Gem1 == nil and _swap_Gem2 == nil then
                    if newPick then
                        for gid, obj in pairs(_GGemTable) do
                            -- 恢复所有宝石的状态
                            obj:rState()
                        end
                    end
                
                    --消除判定((交换之后再判断消除
                    hasPuz = false
                    if _gemPick ~= nil and _gemPick.key ~= gem.key then
                        -- 是否可交换
                        if _gemPick:onIsPuz() and gem:onIsPuz() and gem.bomtype ~= Item_BomRandom and has_Swap(_gemPick, gem) then
                            --交换位置
                            Swap_Gems(_gemPick, gem)
                            hasPuz = true
                        end
                    end
                    if not hasPuz then
                        -- 拾取
                        if newPick then
                            if _gemPick ~= nil then
                                _gemPick:rState()
                            end
                            gem:onPick()
                            onPickGems(gem)
                        end
                    end
                end
            end
        end
    end
    
    

    ------ 统计连击/消除宝石
    _func_Puz_Gems = function(rvalue, bomtpe, isCombo, isStop)
        local comboGem = nil
        --不重复添加
        local glist = {}
        --*****-- 统计
        local gemsums = 0
        for k ,obj in pairs(rvalue) do
            local sums = 0
            for k1, index in pairs(obj.delgems) do
                cgem = _GGemTable[index]
                if cgem ~= nil and glist[cgem.key] == nil then
                    sums = sums + 1
                    glist[cgem.key] = cgem
                end
                
                -- 取消当前拾取的宝石
                if _gemPick ~= nil then
                    if cgem ~= nil and cgem.key == _gemPick.key then
                        _gemPick = nil
                    end
                end
                
                comboGem = cgem
            end
            gemsums = gemsums + sums
            _gameStats:set_datas(Games_Puz, GSPuz_PuzList, {_gameStats:get_datas(Games_Puz, GSPuz_Cot), obj.tpe, sums})
        end
        
        for k, cgem in pairs(glist) do
            _func_deleteGem(cgem, nil, nil, bomtpe, isStop)
        end
        
        
        --*****-- 统计
        _gameStats:set_datas(Games_Puz, GSPuz_Cot)
        --print("Combo::",gemsums)
        
        if isCombo == nil or isCombo == true then
            _gamefunc[PFunc_Combo](_gameStats:get_datas(Games_Puz, GSPuz_Cot), gemsums, comboGem)
        end
    end
    
    _func_changeToBom = function(cgem_new, bomtype)
        if cgem_new ~= nil then
            local anim = cgem_new:changeToBom(bomtype, layer)
            --if anim ~= nil then
            --    layer:addChild(anim,3)
            --end
        end
    end
    
    
    ------消除-PUZ，宝石生成判定
    local cbomTable = {}    -- 爆炸列表
    local cbomidx = 0       -- 当前爆炸索引自增
    local function Move_Gems_CBom_End(obj)
        --print("MCbom,",obj:getTag())
        --- 因为所有生成炸弹都会通过此函数,所以如果同时生成的过多，需要按照顺序爆破
        
        local vtab = cbomTable[obj:getTag()]
        if vtab ~= nil then
            cbomTable[obj:getTag()] = nil
            local rvalue = vtab[1]
            local sogem = vtab[2]
            local bomtype = vtab[3]
            table.remove(cbomTable, obj:getTag())
            
            if rvalue then
                _func_Puz_Gems(rvalue, Item_BomCorss, false, false)
                -----全部消除,生成新的砖块
                local cgem_new = createGems(sogem.row, sogem.col, sogem.tpe)
                _func_changeToBom(cgem_new,bomtype)
            end
        end
    end
    
    
    
    _func_Puz_Puz_Gems = function(rvalue)
        --*****-- 统计
        local gemsums = 0
        for k ,cgem in pairs(rvalue) do
            _func_deleteGem(cgem)
            gemsums = gemsums + 1
        end
    end
    
    _func_Puz_CreateBoms = function(sogems, gemsums, gemlist)
        --消除数量
        --生成的爆炸
        bomtype = nil
        if gemsums == 4 then
            bomtype = Item_Bom
        elseif gemsums == 5 then
            bomtype = Item_BomArce
        elseif gemsums == 6 then
            bomtype = Item_BomCorss
        elseif gemsums >= 7 then
            bomtype = Item_BomRandom
        end
        -- 是否已经购买的炸弹
        if bomtype then
            if GetItems(bomtype) ~= nil and GetItems(bomtype) > 0 and sogems ~= nil then
                -- 宝石生成炸弹效果
                --Play_Effect(sme_BrickHC)
                --聚集在一起
                local maxtime = 0
                sogems.delgems = {}
                local sogem = _GGemTable[getIndex(sogems.row, sogems.col)]
                
                if sogem == nil then
                    return false
                end
                
                local x, y = sogem:GetPosition()
                sogem.isHeCheng = true
                table.insert(sogems.delgems, getIndex(sogem.row, sogem.col))
                for k , cgem in pairs(gemlist) do
                    local mypx, mypy = cgem.img:getPosition()
                    local vlenght = ccpLength(ccp(mypx - x, mypy - y))
                    local mtime = Anim_MoveTimes * (vlenght/gemSize)
                    
                    if mtime > maxtime then
                        maxtime = mtime
                    end
                    
                    if sogems.key ~= cgem.key then
                        cgem:runAction_MoveTo(mtime, ccp(x,y))
                        
                        table.insert(sogems.delgems, getIndex(cgem.row, cgem.col))
                    end
                    
                    cgem.isHeCheng = true
                end
                --_func_Puz_Gems({sogems})
                
                if sogem then
                    sogem:runAction_MoveTo(maxtime+0.01, ccp(x,y), Move_Gems_CBom_End)
                    _moveSums = _moveSums + 1
                    -- 效果结束生成宝石
                    cbomTable[sogem.key] = {{sogems},sogem,bomtype}
                else
                    print("errow!!!!!!!!!!!")
                end
            end
            return true
        end
        return false
    end
    
    _func_Puz_Bom_Gems = function(rvalue)
        -------------判断炸弹生成之前,需要先引爆所有炸弹
        ----先引爆
        local hasbom = false
        
        local fbgemlist = {}
        for k ,obj in pairs(rvalue) do
            local sums = 0
            for k1, index in pairs(obj.delgems) do
                cgem = _GGemTable[index]
                if cgem ~= nil then
                    if fbgemlist[cgem.key] == nil then
                        fbgemlist[cgem.key] = getIndex(cgem.row, cgem.col)
                        if cgem.bomtype then
                            hasbom = true
                            _func_UseToBom(cgem, cgem.bomtype)
                        end
                    end
                end
            end
        end
        
        -- 如果有炸弹,则先爆炸后重新判定
        if hasbom then
            local rvalueSS = {}
            for k , index in pairs(fbgemlist) do
                cgem = _GGemTable[index]
                if cgem ~= nil then
                    local has1, rvalue1 = _func_has_Puz_Gem(_GGemTable, cgem.tpe, cgem.row, cgem.col, cgem.key)
                    if has1 then
                        for k, obj in pairs(rvalue1) do
                            table.insert(rvalueSS, obj)
                        end
                    end
                end
            end
            
            -- 如果有可消除,就重复消除操作
            if #rvalueSS > 0 then
                _func_Puz_Bom_Gems(rvalueSS)
            end
            _func_Puz_Gems(rvalue)
            return false
        end
        
        ---- 重叠的砖块队列需要联合起来
        if #rvalue >= 2 then
            local _idx = 1
            while _idx < #rvalue do
                local objs1 = rvalue[_idx]
                local _idx2 = _idx+1
                while _idx2 < #rvalue do
                    local objs2 = rvalue[_idx2]
                    
                    local nobj = nil
                    if objs1 ~= nil and objs2 ~= nil then
                        for k1, index1 in pairs(objs1.delgems) do
                            for k2, index2 in pairs(objs2.delgems) do
                                if index1 == index2 then
                                    -- 连接两个
                                    local ndelgems = {}
                                    table.insert(ndelgems, index1)
                                    for vk1, vindex1 in pairs(objs1.delgems) do
                                        if vindex1 ~= index1 then
                                            table.insert(ndelgems, vindex1)
                                        end
                                    end
                                    for vk2, vindex2 in pairs(objs2.delgems) do
                                        if vindex2 ~= index1 then
                                            table.insert(ndelgems, vindex2)
                                        end
                                    end
                                    nobj = true
                                    
                                    objs1.delgems = ndelgems
                                    -- 以连接点为主砖块
                                    _ncgem = _GGemTable[index1]
                                    objs1.key = _ncgem.key
                                    objs1.row = _ncgem.row
                                    objs1.col = _ncgem.col
                                    objs1.tpe = _ncgem.tpe
                                    
                                    -- 清除
                                    rvalue[_idx2] = nil
                                    
                                    break
                                end
                            end
                            if nobj ~= nil then
                                break
                            end
                        end
                    end
                    
                    if nobj ~= nil then
                        _idx2 = _idx2 + 2
                    else
                        _idx2 = _idx2 + 1
                    end
                end
                _idx = _idx + 1
            end
        end
        
        --- 合成创建炸弹
        local sogems = nil
        for k ,obj in pairs(rvalue) do
            local sums = 0
            local gemlist = {}
            for k1, index in pairs(obj.delgems) do
                cgem = _GGemTable[index]
                if cgem ~= nil then
                    if gemlist[cgem.key] == nil then
                        gemlist[cgem.key] = cgem
                        sums = sums + 1
                    end
                end
            end
            
            hasbom = _func_Puz_CreateBoms(obj, sums, gemlist)
        end
        
        --_func_Puz_Gems(rvalue)
            
        -- 就算炸弹,这些连接的砖块也要消除
        local comboGem = nil
        local sums = 0
        for k,index in pairs(fbgemlist) do
            local cgem = _GGemTableKeys[k]
            if cgem and cgem.bomtype == nil and not cgem.isHeCheng then
                _func_deleteGem(cgem)
            end
            sums = sums + 1
            
            comboGem = cgem
        end
        _gamefunc[PFunc_Combo](_gameStats:get_datas(Games_Puz, GSPuz_Cot), sums, comboGem)
    end
    
    -----------------------------------触摸操作
    -- 拾取
    local function getPickGem(x, y)
        for gid, obj in pairs(_GGemTable) do
            if obj:isPick(x,y) then
                return obj
            end
        end
        return nil
    end
    
    
    local beginPx, beginPy = 0,0
    local _mouse_x , _mouse_y = 0,0
    local function onPickMoved(x,y)
        local mx = math.abs(x - beginPx)
        local my = math.abs(beginPy - y)
        local arce = 20
        if _gemPick ~= nil and (mx > arce or my > arce) then
            local obj = nil
            if mx > my then
                -- 左右
                if x - beginPx > 0 then
                    -- 右
                    obj = _GGemTable[getIndex(_gemPick.row, _gemPick.col + 1)]
                else
                    -- 左
                    obj = _GGemTable[getIndex(_gemPick.row, _gemPick.col - 1)]
                end
            else
                -- 上下
                if y - beginPy > 0 then
                    -- 上
                    obj = _GGemTable[getIndex(_gemPick.row - 1, _gemPick.col)]
                else
                    -- 下
                    obj = _GGemTable[getIndex(_gemPick.row + 1, _gemPick.col)]
                end
            end
            if obj ~= nil and obj:setPick() then
                Pick_Gems(obj, false)
            end
        end
    end
    -- 按下
    local function onTouchBegin(x, y)
        --丢弃超出范围的操作
        --print(x,y, gemPosx, gemEndPx, gemPosy, gemEndPy)
        if x < gemPosx - GridWidth/2 or x > gemEndPx + GridWidth/2 or y < gemPosy - GridHeight/2 or y > gemEndPy + GridHeight/2 then
            return true
        end
        
        local obj = _GGemTable[getIndex(getGemGrid(x, y))]
        --print(obj, obj:setPick(), obj.isremove, obj.isMoved, obj.isBomed, obj.GoToDelete)
        if obj ~= nil and obj:setPick() then
            Pick_Gems(obj)
        end
        
        beginPx = x
        beginPy = y
        return true
    end
    
    
    
    -- 按住移动
    local function onPickMoved_Bizz(x,y)
        -- 判断当前宝石是否还可以拾取
        --如果当前没有拾取成功,则判定拾取
        if _gemPick == nil then
            onTouchBegin(x,y)
        else
            if not _func_on_PickBizz(_GGemTable, _gemPick) then
                --gem:onPick()
                _func_Set_GemPos(_gemPick, _gemPick.row, _gemPick.col)
                _gemPick = nil
                return
            end
    
    
            -- 如果向旁边移动,并且旁边已经有宝石了,则不更新x坐标值
            if x < gemPosx then
                x = gemPosx
            end
            if x > gemEndPx then
                x = gemEndPx
            end
            if y < gemPosy then
                y = gemPosy
            end
            if y > gemEndPy then
                y = gemEndPy
            end
    
    
            --如果当前位置与之前的位置不碰撞,则更新至当前位置
            local r, c = getGemGrid(x, y)
            if r ~= _gemPick.row or c ~= _gemPick.col then
                -- 当前位置必须为空
                if _GGemTable[getIndex(r,c)] == nil then
                    local lr, lc = _gemPick.row, _gemPick.col
                    _func_Set_GemPos(_gemPick, r, c, false)
                    _gemPick:onMoveTo(gdv(x),gdv(y))
                    -- 移动之后,触发一次重新排列
                    -- 因为只有移除了一颗宝石,所以只需要判断当前位置之后的位置即可
                    _Fill_UToD_Lite_Bizz(lr, lc)
                end
            end
    
        
            local gemx, gemy = getGemPosNoSc(_gemPick.row, _gemPick.col) --_gemPick:GetPosition()
            local tox, toy = x,y
            -- 移动过后还不可以直接移动过去,因新位置的中间可能有阻挡物,所以还需要判断阻挡位置
            local pr, pc = getGemGrid(gemx, toy)
            
            if x < gemx then
                local i = pc - 1
                while i >= 0 do
                    local _gx, _gy = getGemPosNoSc(pr, i)
                    if _gx + GridWidth < x then
                        break
                    end
                    
                    local _gem = _GGemTable[getIndex(pr, i)]
                    if _gem ~= nil then
                        tox = _gx + GridWidth
                        break
                    end
                    i = i - 1
                end
            elseif x > gemx then
                local i = pc + 1
                while i < Gems_Cols do
                    local _gx, _gy = getGemPosNoSc(pr, i)
                    if _gx - GridWidth >= x then
                        break
                    end
                        
                    local _gem = _GGemTable[getIndex(pr, i)]
                    if _gem ~= nil then
                        tox = _gx - GridWidth
                        break
                    end
                    i = i + 1
                end
            end
            
            pr, pc = getGemGrid(tox, gemy)
            if y > gemy then
                local i = pr - 1
                while i >= 0 do
                    local _gx, _gy = getGemPosNoSc(i,pc)
                    if _gy - GridHeight >= y then
                        break
                    end
                        
                    local _gem = _GGemTable[getIndex(i, pc)]
                    if _gem ~= nil then
                        toy = _gy - GridHeight
                        break
                    end
                    i = i - 1
                end
            elseif y < gemy then
                local i = pr + 1
                while i < Gems_Rows do
                    local _gx, _gy = getGemPosNoSc(i,pc)
                    if _gy + GridHeight <= y then
                        break
                    end
                    
                    local _gem = _GGemTable[getIndex(i, pc)]
                    if _gem ~= nil then
                        toy = _gy + GridHeight
                        break
                    end
                    i = i + 1
                end
            end
            _gemPick:onMoveTo(gdv(tox),gdv(toy))
        end
    end
    
    
    local function onTouchMoved(x, y)
        _mouse_x = x
        _mouse_y = y
        -- 模式:bizz
        if _gameMode == GameMode_Bizz then
            onPickMoved_Bizz(x, y)
        elseif _gameMode == GameMode_Puz and _gemPick ~= nil then
            ---  移动过程中就判断消除
            onPickMoved(x, y)
        end
    end
    -- 释放
    local function onTouchEnded(x, y)
        -- 模式:bizz
        if _gameMode == GameMode_Bizz then
            if _gemPick ~= nil then
                -- 停止后,移动至当前位置的最下文空位,判定消除
                local pgem = _gemPick
                _gemPick.isMoved = false
                _gemPick = nil
                
                local lrow = pgem.row
                local lcol = pgem.col
                
                --判断下面是否有空位,有则排列
                local dgem = _GGemTable[getIndex(lrow+1, lcol)]
                if dgem == nil and lrow + 1 ~= Gems_Rows then
                    --放手之后排列即可
                    _Fill_UToD_Lite_Bizz(lrow+1, lcol)
                else
                    _func_Set_GemPos(pgem, lrow, lcol)
                end
            end
            --停止移动/放置/判定消除
            _gemPick = nil
        elseif _gameMode == GameMode_Clicked then
        
        else
            --- 结束时会判断当前手势,向左向右向上向下,根据手势交换周围的宝石
            onPickMoved(x, y)
        end
    end
    -- 触摸操作
    local function onTouch(eventType, x, y)
        if _gamePause then
            return
        end
        
        x,y = gdvc(x), gdvc(y)
    
        if eventType == CCTOUCHBEGAN then
            return onTouchBegin(x, y)
        elseif eventType == CCTOUCHMOVED then
            return onTouchMoved(x, y)
        elseif eventType == CCTOUCHENDED then
            return onTouchEnded(x, y)
        end
    end
    
    ----------------- 更新回调
    local _onGameRun = nil
    
    local _frame = 0
    local function update(dt)
        if not _GameEndRun then
            _gamefunc[PFunc_Timer](_frame, dt)
        end
        
        if _GameFirst then
            return
        end
        
        if _GameEndRun then
            return
        end
        
        _frame = _frame + 1
        ------3秒后开始游戏
        --if _gameMode == GameMode_Bizz and _frame <= 60 then
        --    if _frame == 60 then
        --        for k, cgem in pairs(_GGemTable) do
        --            Move_Gems_End(cgem.img)
        --        end
        --    end
        --    return
        --end
        
        
        -------- 水晶时空模式,每五秒会生成一排宝石
        if _gameMode == GameMode_Bizz then
            _GameMode_Bizz_NewLineLt = _GameMode_Bizz_NewLineLt + dt
            if _GameMode_Bizz_NewLineLt >= _GameMode_Bizz_NewLine then
                _GameMode_Bizz_NewLineLt = _GameMode_Bizz_NewLineLt - _GameMode_Bizz_NewLine
                -- 从上方生成一排
                Fill_Gems_FirstRow()
                
                _gamefunc[PFunc_Complete]()
            end
        end
        
        -- 点击暂时,时间到后才暂停
        --print(_gamePause, _gameRun)
        if _gamePause == _gameRun then
            _onGameRun()
        end
        
        if _gameMode == GameMode_Bizz or _gameMode == GameMode_Puz then
            if _frame % 300 == 0 then
                local idx = math.random(1,#G_PuzGemsList)
                gtype = G_PuzGemsList[idx]
                table.foreach(_GGemTable, function(k,cgem)
                    if cgem ~= nil then
                        if not cgem.isremove then
                            if cgem ~= nil and cgem.tpe == gtype then
                                cgem:onAnimtion()
                            end
                        else
                            _GGemTable[k] = nil
                        end
                    end
                end)
            end
        end
    end
    
    ---暂停游戏
    _onGameRun = function()
        if not _gameRun then
            _baseLayer_entry = CCDirector:sharedDirector():getScheduler():scheduleScriptFunc(update, 1.0/60.0, false)
            _gameRun = true
        else
            if _baseLayer_entry ~= nil then
                CCDirector:sharedDirector():getScheduler():unscheduleScriptEntry(_baseLayer_entry)
            end
            _baseLayer_entry = nil
            _gameRun = false
        end
    end
    
    local function SpriteEase_onEnterOrExit(tag,tag2)
        if not _joinGame then
            _joinGame = true
            _gameRun = false
            index = 0
            _onGameRun()
        else
            _joinGame = false
            _gameRun = true
            _onGameRun()
        end
    end
    
    
    -- 注册进入/退出事件
    layer:registerScriptHandler(SpriteEase_onEnterOrExit)
    
    -- 开始触摸
    layer:setTouchEnabled(true)
    layer:registerScriptTouchHandler(onTouch)
    
    
    
    
    
    _GameFirst = true
    
    --Init_GameSound()
    
    return layer
end


-------------重新排列移动所有区域的砖块
Func_BeginResFills = function()
    table.foreach(_GGemTable, function(k, cgem)
        if cgem ~= nil then
            local tx, ty = getGemPos(-(Gems_Rows-cgem.row+2), cgem.col)
            cgem:onMoveTo(tx,ty)
            AddMoveToGems(cgem)
            --print(cgem.row,cgem.col)
        end
    end)
end











